package edu.towson.cosc716.models;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

import edu.towson.cosc716.interfaces.ObservableInterface;
import edu.towson.cosc716.interfaces.ObserverInterface;
import edu.towson.cosc716.interfaces.Strategy;
import edu.towson.cosc716.iterators.GetOrdersByTable;
import edu.towson.cosc716.strategies.DefaultStrategy;
import edu.towson.cosc716.strategies.SimilarItem;

// TODO: Auto-generated Javadoc
/**
 * The Class Orders.
 */
public class Orders implements ObservableInterface {

	/** The orders. */
	private LinkedList<Order> orders = new LinkedList<Order>();
	
	/** The observers. */
	private List<ObserverInterface> observers = new ArrayList<ObserverInterface>();
	
	/** The strategy. */
	private Strategy strategy;
	
	/**
	 * Instantiates a new orders.
	 */
	public Orders() {
		//strategy = new DefaultStrategy();
		strategy = new SimilarItem();
	}
	
	/**
	 * Adds the.
	 *
	 * @param order the order
	 */
	public void add(Order order) {
		this.orders.add(order);
	}
	
	/**
	 * Removes the.
	 *
	 * @param order the order
	 */
	public void remove(Order order) {
		this.orders.remove(order);
	}
	
	/**
	 * Gets the next order.
	 *
	 * @param order the order
	 * @return the next order
	 */
	public Order getNextOrder(Order order) {
		List<Object> arguments = new ArrayList<Object>();
		arguments.add(Constants.ObjectTypes.ORDER);
		arguments.add(order);
		return (Order)strategy.nextItem(orders, arguments);
	}
	
	/**
	 * Removes the.
	 *
	 * @return the order
	 */
	public Order remove() {
		return orders.remove();
	}
	
	/**
	 * Prune inactive.
	 */
	public void pruneInactive() {
		Iterator orderIter = this.orders.iterator();
		Order currOrder;
		while (orderIter.hasNext()) {
			currOrder = (Order) orderIter.next();
			if (currOrder.getActive() == false) {
				this.remove(currOrder);
			}
		}
	}
	
	/**
	 * Gets the orders by table.
	 *
	 * @param tableId the table id
	 * @return the orders by table
	 */
	public GetOrdersByTable getOrdersByTable(int tableId) {
		return new GetOrdersByTable(tableId, orders);
	}
	
	/**
	 * Gets the list.
	 *
	 * @return the list
	 */
	public LinkedList getList() {
		return orders;
	}

	
	/**
	 * Order count by table.
	 *
	 * @param tableId the table id
	 * @return the int
	 */
	public int orderCountByTable(int tableId) {
		int count = 0;
		for (Object order : orders.toArray()) {
			Order orderBean = (Order)order;
			if (order == null) {

			} else if (orderBean.getTableId() == tableId) {
				count++;
			}
		}
		return count;
	}
	
	/**
	 * Gets the orders for table.
	 *
	 * @param tableId the table id
	 * @return the orders for table
	 */
	public List<Order> getOrdersForTable(int tableId) {
		List<Order> tableOrders = new ArrayList<Order>();
		Iterator<Order> iterator = orders.listIterator();
		while (iterator.hasNext()) {
			Order order = iterator.next();
			
			if (order != null && order.getTableId() == tableId) {
				tableOrders.add(order);
			}
		}
		return tableOrders;
	}

	/**
	 * Gets the size.
	 *
	 * @return the size
	 */
	public int getSize() {
		return orders.size();
	}
	
	/**
	 * Update all.
	 */
	public void updateAll() {
		for (int i = 0; i < observers.size(); i++) {
			observers.get(i).update(this);
		}
	}

	/* (non-Javadoc)
	 * @see edu.towson.cosc716.interfaces.ObservableInterface#addObserver(edu.towson.cosc716.interfaces.ObserverInterface)
	 */
	@Override
	public void addObserver(ObserverInterface o) {
		observers.add(o);
		
	}

	/* (non-Javadoc)
	 * @see edu.towson.cosc716.interfaces.ObservableInterface#removeObserver(edu.towson.cosc716.interfaces.ObserverInterface)
	 */
	@Override
	public void removeObserver(ObserverInterface o) {
		observers.remove(o);
		
	}

	/* (non-Javadoc)
	 * @see edu.towson.cosc716.interfaces.ObservableInterface#getType()
	 */
	@Override
	public String getType() {
		
		return Constants.ObjectTypes.ORDERS;
	}
	
}
